﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using Models;
using BLL;
using SocketHelper;
using System.Threading;
using System.Diagnostics;
using System.Configuration;
using MySocketHelper;
using System.Reflection;
using SerialPortHelper;

namespace AGVControlSystemPro
{
    public delegate void ShowInfo(); //创建显示AGV委托
    public delegate void ServerSend(string ip,OrderList objOrderList);//创建一个发送数据的委托
    public delegate void CallInfoImport(List<ExCall> list);//创建一个呼叫信息加载的委托
    public delegate void DeleteCallInfo(int index);//创建一个删除已发送呼叫信息的委托
    public delegate void IPTypeOutput(); //创建一个IP类型委托
    public delegate void TrafficView(List<TrafficInfo> objTraffic);//创建一个显示交管信息的委托
    public delegate void WatchBoard(WatchBoards objWatchBoard);//创建一个看板系统显示委托变量
    public partial class FrmMain : Form
    {
        private AGVInfoManager objAGVInfoManager = new AGVInfoManager();//AGV基本信息访问类
        private AGVCommunicationManager objAGVCommunicationManager = new AGVCommunicationManager();//调度系统协议
        private TrafficManager objTrafficManager = new TrafficManager();//交管访问函数
        private IPTypeManager objIPTypeManager = new IPTypeManager();//IP地址类型访问类
        private RemoteIOManager objRemoteIOManager = new RemoteIOManager(); //远程IO访问类
        SocketManager m_socket = null; //AGV服务端的定义
        SocketManager remoteSocket = null; //远程IO服务端的定义

        private ServerHelper objServerHelper = new ServerHelper();//定义一个socket服务端访问类
        private List<string> LoginIPList = new List<string>(); //上线IP列表
        //保存了服务器端所有负责调用通信套接字.Receive方法的线程 
        private List<ExCall> listExCall = new List<ExCall>();//定义一个存储当前所有呼叫的集合
        private List<ExCall> listFinishCall = new List<ExCall>();//定义一个存储呼叫执行完成的集合
        private List<IPType> listIPType = new List<IPType>();//定义一个存储IP类型数据的集合
        private List<TrafficInfo> listTraffic = new List<TrafficInfo>();//创建一个存储当前交管的信息集合
        private List<TrafficInfo> listTrafficOrder = new List<TrafficInfo>();//用来存储所有数据库中交管指令的集合，初始化从数据库获取
        private List<AGVInfo> listLastAGVInfo = new List<AGVInfo>();//创建一个存储当前在线AGV的信息列表
        private Dictionary<string, SocketClientManager> dicSocketClient = new Dictionary<string , SocketClientManager>();//定义一个存储客户端的集合
        private AGVInfo objLastAgvInfo = new AGVInfo(); //当前AGV信息
        private bool isStartTraffic = false;//是否开启交管
        private bool isFinishTrafficControl = false; //是否已完成交管处理，预防数据被覆盖
        private bool isRun = false;//是否启动调度扫描
        private bool exCallLock = false; //呼叫显示上锁标志位，预防呼叫显示和呼叫完成删除时出现故障
        private bool isConnectServer = false;//是否连接服务端的标志位
        Thread objThread = null;//调度系统线程
        Thread threadMapDispaly = null;//电子地图线程
        public WatchBoard WatchBoarShow;//根据委托创建委托对象
        //public TrafficView TrafficInfoShow;//根据委托创建委托对象
        public event TrafficView TrafficInfoShow;
        Stopwatch sysRunTime = new Stopwatch();
        private string alarmIP = string.Empty; //报警远程IO的IP地址
        private bool alarmSend = false; //报警信息是否已经发送
        private bool alarmClear = false;//报警已清除
        private FileNameAddress currentFileNameAddress = new FileNameAddress();//存储当前的打开文档数据信息
        private List<LandNode> currentListNodes = new List<LandNode>();//存储当前所有地标信息
        private List<Label> listAGVLabel = new List<Label>();//存储AGV标签
        string filePath = System.Windows.Forms.Application.StartupPath + @"\ProjectConfig.ini";//配置文件路径
        private static readonly object obj = new object(); //AGV数据接收lock对象
        private static readonly object obj1 = new object(); //远程IO数据接收lock对象
        AGVInfoManager infoManager = new AGVInfoManager();
        System.Timers.Timer t = new System.Timers.Timer( 10* 60 * 1000);
        System.Timers.Timer s = new System.Timers.Timer(60 * 1000);
        public FrmMain()
        {
            InitializeComponent();
            //用户名显示
            this.lblAdminName.Text = "["+Program.currentAdmins.AdminName+"]";
            this.lblPort.Text = ConfigurationManager.AppSettings["Port"].ToString();//服务器端口号
            this.lblRemotePort.Text = ConfigurationManager.AppSettings["RemotePort"].ToString();//服务器端口号
            alarmIP = ConfigurationManager.AppSettings["AlarmRemoteIOIP"].ToString();//报警远程IO的IP地址
            
            //--------------------------获取本地IP--------------------------//
            //ip地址列表
            string hostname = Dns.GetHostName();
            IPHostEntry localhost = Dns.GetHostByName(hostname);
            IPAddress localaddr = localhost.AddressList[0];
            //显示本地IP
            this.lblLocalIP.Text = localaddr.ToString();
            //加载AGV信息
            this.dgvAGV.AutoGenerateColumns = false;
            ShowAGVInfo();
            //获取IP地址信息
            this.listIPType = objIPTypeManager.GetGetAllIPType1();
            //获取所有交管指令数据
            GetAllTrafficOrder();
            
            //启动调度线程
           // ParameterizedThreadStart pts = new ParameterizedThreadStart(TaskScheduling);
            objThread = new Thread(TaskScheduling);
            objThread.IsBackground = true; //该线程为后台线程
            objThread.Start(); //开始线程
            //从数据库获取当天未完成的呼叫信息                      
            CommonMethods.ListPreCall = objRemoteIOManager.GetUnfinishCallByTime(DateTime.Now);           
                  
            //统计系统运行时间开始
            sysRunTime.Start();
            //电子地图初始化化
            MapPictureInit();
           //删除完成记录
            this.objRemoteIOManager.DeleteFinishCallByTime(DateTime.Now.AddDays(-30).ToShortDateString());
            objRemoteIOManager.OnSendRemoteData += EventSendRemoteData;//远程IO数据发送办法的关联 
        }

        #region  初始化
        /// <summary>
        /// 电子地图初始化化
        /// </summary>
        private void MapPictureInit()
        {
            //获取电子地图的工程
            string pictureId = new Common.INIFileHelper(filePath).IniReadValue("工程文件", "项目编号");           
            this.currentFileNameAddress.ID = Convert.ToInt32(pictureId);
            this.currentFileNameAddress.FileName = new Common.INIFileHelper(filePath).IniReadValue("工程文件", "工程名称");
            //if (CommonMethods.LanguageId == 3) this.Text = "【AGVシステム】-- プロジェクトの名前：" + this.currentFileNameAddress.FileName;
            //else this.Text = "【AGV调度系统】-- 项目工程：" + this.currentFileNameAddress.FileName;
            //【1】图片加载
            LoadPicture(pictureId);
            //【2】地标信息加载
            this.currentListNodes = new LandNodeManager().GetAllLandNodesById(pictureId);
            //【3】AGV加载
            if(this.currentListNodes.Count!=0) MapAGVInit();
            //【4】在线列表加载
            ShowOnlineStatus();
        }
        /// <summary>
        /// AGV电子地图标签初始化
        /// </summary>
        private void MapAGVInit()
        {
            int x = 50, y = 50;
            this.pictureBoxMap.Controls.Clear(); //清空当前所有控件
            this.listAGVLabel.Clear();//情况集合避免重复添加
            foreach (AGVInfo item in listLastAGVInfo)
            {
                Label objLabel = new Label();//创建一个Label控件对象
                objLabel.Size = new System.Drawing.Size(25, 16);
                objLabel.BackColor = Color.Silver; //背景颜色
                objLabel.ForeColor = Color.White;//字体颜色
                objLabel.TextAlign = ContentAlignment.MiddleCenter;
                objLabel.AutoSize = false;
                objLabel.Font = new Font("宋体", 10, FontStyle.Bold); //第一个是字体，第二个大小，第三个是样式，
                 objLabel.Location = new System.Drawing.Point(x , y);
                objLabel.Text = item.AGVId.ToString();
                objLabel.Name = item.AGVName;
                //人机界面添加一个Label控件
                this.pictureBoxMap.Controls.Add(objLabel); //添加一个控件
                objLabel.MouseEnter +=objLabel_MouseEnter; //注册鼠标事件，用来提示当前AGV信息
                this.listAGVLabel.Add(objLabel);
                x = x + 100;
            }
        }

        private void objLabel_MouseEnter(object sender, EventArgs e)
        {
            AGVInfo objAGV = this.listLastAGVInfo.Find(s=>s.AGVName ==((Label)sender).Name);
            string str = string.Empty;
            if (CommonMethods.LanguageId == 3) str = string.Format("現在の状態：{0}\r\nスピード：{1} \r\n電気の量：{2}V \r\nタスクの状態：{3}", objAGV.PreAGVStatus, objAGV.Speed, objAGV.Electricity, "暇がない");
            else str = string.Format("当前状态：{0}\r\n速度：{1} \r\n电量：{2}V \r\n任务状态：{3}", objAGV.PreAGVStatus, objAGV.Speed, objAGV.Electricity, "空闲");
            this.toolTip1.ToolTipTitle = ((Label)sender).Name;
            this.toolTip1.SetToolTip((Label)sender,str);
        }
        private void ShowOnlineStatus()
        {
            List<AGVInfo> listAGV = new AGVInfoManager().GetAGVInfo("1"); //AGV配置数据获取
            List<ExCall> listRemoteIO = new RemoteIOManager().GetRemoteIO();//远程IO配置数据获取
            //根目录节点添加
            List<OnlineStatus> list = new List<OnlineStatus>() 
            {
                new OnlineStatus(){Id = 1,ParentId = 0,Text = "AGV",IP = "AGV",OnLineCount = 0,Count = listAGV.Count},
                new OnlineStatus(){Id = 2,ParentId = 0,Text = "远程IO",IP = "远程IO",OnLineCount = 0,Count = listRemoteIO.Count},
                 new OnlineStatus(){Id = 3,ParentId = 0,Text = "其他",IP = "其他",OnLineCount = 0,Count =0},
            };
            //根目录AGV节点下节点添加
            for (int i = 0; i < listAGV.Count; i++)
            {
                list.Add(new OnlineStatus() {Id = 100 +i,ParentId = 1,Text = listAGV[i].AGVName,IP = listAGV[i].IP });
            }
            //远程IO目录下节点添加
            for (int i = 0; i < listRemoteIO.Count; i++)
            {
                list.Add(new OnlineStatus() {Id = 200+i,ParentId = 2,Text = listRemoteIO[i].RemoteName,IP = listRemoteIO[i].IP });
            }
            for (int i = 0; i < list.Count; i++)
            {
                //【1】创建根节点
                if (list[i].ParentId == 0)
                {
                    TreeNode objNode = new TreeNode()
                    {
                        Name = list[i].IP,
                        Text = list[i].Text + "("+list[i].OnLineCount +"/"+list[i].Count + ")",
                        Tag = 0,
                        ForeColor = Color.Blue
                    };
                    //创建二级节点
                    for (int j = 0; j < list.Count; j++)
                    {
                        if (list[j].ParentId == list[i].Id)
                        {
                            string txt = "{0} \r\n {1}({2})";
                            txt = string.Format(txt, list[j].Text,list[j].IP,list[j].Status);
                            //创建一个一级节点下的二级节点
                            objNode.Nodes.Add(new TreeNode() 
                            { 
                                Name = list[j].IP,
                                Text = txt,
                                Tag = list[j].Text,
                                ForeColor = Color.Red
                            });
                        }
                        
                    }
                    this.tvwOnlineStatus.Nodes.Add(objNode); //添加节点
                }
            }
        }
        #endregion

        #region 委托使用的办法
        /// <summary>
        /// AGV信息加载
        /// </summary>
        private  void ShowAGVInfo()
        {
            this.dgvAGV.DataSource = null;
            //new Common.DataGridViewStyle().DgvStyle4(this.dgvAGV);
            listLastAGVInfo = objAGVInfoManager.GetAGVInfo("1"); //获取启动的AGV，并初始化当前状态
            this.dgvAGV.DataSource = listLastAGVInfo; //DataGridView显示AGV状态
        }
        /// <summary>
        /// 构造一个委托一样的办法模型
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="objOrderList"></param>
        private void SendData(string ip, OrderList objOrderList)
        {
        

            try
            {
                //bool result = objAGVCommunicationManager.SendDataByIP(ip, this.objServerHelper.SocketDic,objOrderList);
                AsyncUserToken token = m_socket.ClientList.Find(s => s.IPAddress.ToString() == ip);
                if (token != null) this.m_socket.SendMessage(token, objAGVCommunicationManager.GetSendData(objOrderList));
                else MessageBox.Show("发送失败，该AGV可能已掉线或不存在", "调试提示");
            }
            catch (Exception ex)
            {
                
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 构造一个呼叫信息一样办法模型（委托调用）
        /// </summary>
        /// <param name="list"></param>
        private void LoadCallInfo(List<ExCall> list)
        {
           // listExCall.AddRange(list); //数据加载
            CommonMethods.ListPreCall.AddRange(list);
            CommonMethods.StatndbyCallDisplayFlag = true;//显示置位
        }
        private void CallFinish(int index)
        {
           // listExCall.RemoveAt(index);
            CommonMethods.ListPreCall.RemoveAt(index);
            CommonMethods.StatndbyCallDisplayFlag = true;//显示置位
        }
        private void ShowTypeIP()
        {
            this.listIPType = objIPTypeManager.GetGetAllIPType1();
        }
        /// <summary>
        /// 显示行号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvAGV_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Common.DataGridViewStyle.DgvRowPostPaint(this.dgvAGV,e);
        }
        /// <summary>
        /// 获取所有AGV交管指令的信息
        /// </summary>
        private void GetAllTrafficOrder()
        {
            this.listTrafficOrder = objTrafficManager.GetAlltrafficInfo();
        }
        /// <summary>
        /// 向远程IO发送数据
        /// </summary>
        /// <param name="token"></param>
        /// <param name="address"></param>
        private void EventSendRemoteData(AsyncUserToken token, byte address)
        {
            byte[] sendBuf = new byte[8] {0x01, 0x05,0x00,0x00,0x00,0x00,0x00,0x00}; //初始化远程IO输出发送数据
            byte[] crc = new byte[6] { 0x01, 0x05, 0x00, 0x00, 0x00, 0x00}; //初始化远程IO输出发送数据
            sendBuf[3] = address;//地址码
            sendBuf[4] = 0xFF;//IO输出置位
            crc[3] = address;//地址码
            crc[4] = 0xFF;//IO输出置位
            byte[] CRCVal = Common.CRCVerify.CRC16(crc);
            sendBuf[6] = CRCVal[1];
            sendBuf[7] = CRCVal[0];
            remoteSocket.SendMessage(token, sendBuf);
            Thread.Sleep(500);
            sendBuf[3] = address;//地址码
            sendBuf[4] = 0x00;//IO输出置位
            crc[3] = address;//地址码
            crc[4] = 0x00;//IO输出置位
            byte[] CRCVal1 = Common.CRCVerify.CRC16(crc);
            sendBuf[6] = CRCVal1[1];
            sendBuf[7] = CRCVal1[0];
            remoteSocket.SendMessage(token, sendBuf);
        }
        #endregion 

        #region 服务端操作函数
        /// <summary>
        /// 启动监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.btnStart.Text == "启动系统  " || this.btnStart.Text == "起動システム")
                {
                    //AGV服务端参数的配置
                    int agvPort = Convert.ToInt32(this.lblPort.Text.Trim());//服务器端口号
                    IPAddress agvIP = IPAddress.Parse(this.lblLocalIP.Text.Trim()); //服务器IP
                    IPEndPoint agvPoint = new IPEndPoint(agvIP, agvPort);
                    int count = Convert.ToInt32(ConfigurationManager.AppSettings["SocketCount"]); //获取连接个数
                    m_socket = new SocketManager(count, 16);   //创建一个Socket 监听数20，字节1024
                    m_socket.Init(); //初始化Socket
                    //远程IO服务端参数配置
                    int remotePort = Convert.ToInt32(this.lblRemotePort.Text.Trim());
                    IPAddress remoteIP = IPAddress.Parse(this.lblLocalIP.Text.Trim()); //服务器IP
                    IPEndPoint RemotePoint = new IPEndPoint(remoteIP, remotePort);
                    remoteSocket = new SocketManager(count, 16);   //创建一个Socket 监听数20，字节1024(修改：把1024修改成16)20180416
                    remoteSocket.Init(); //初始化Socket

                    if (m_socket.Start(agvPoint) && remoteSocket.Start(RemotePoint)) //监听成功则启动
                    {
                        //t.Elapsed += AddAgv;
                        //t.Start();
                        m_socket.ClientNumberChange += AcceptInfo; //关联监听事件
                        m_socket.ReceiveClientData += ReceiveMsg; //关联客户端数据接收事件
                        remoteSocket.ClientNumberChange += RemoteAcceptInfo; //关联监听事件
                        remoteSocket.ReceiveClientData += RemoteReceiveMsg; //关联客户端数据接收事件
                        if (CommonMethods.LanguageId == 3) this.btnStart.Text = "停止システム";
                        else this.btnStart.Text = "停止系统  ";
                        this.timAGVStaus.Start();//启动状态扫描定时器
                        isRun = true;//启动调度扫描
                        StartTrafficThread(true);//启动交管
                        this.timAlarm.Start();//报警定时器开始
                        //启动电子地图显示线程
                        if (this.currentListNodes.Count != 0)
                        {
                            threadMapDispaly = new Thread(MapDispalyThread);
                            threadMapDispaly.IsBackground = true;
                            threadMapDispaly.Start();//开始线程
                        }
                    }
                    //s.Elapsed += oneAddAgv;
                    //s.Start();
                    // StartClientConnectThread(true);
                }
                else
                {
                    ServerClose();//关闭服务器
                    if (CommonMethods.LanguageId == 3) this.btnStart.Text = "起動システム";
                    else this.btnStart.Text = "启动系统  ";
                    this.timAGVStaus.Stop();//停止状态扫描定时器
                    this.timAlarm.Stop();//报警定时器失效
                    isRun = false;//停止调度扫描
                    StartTrafficThread(false);//停止交管线程
                    isStartTraffic = false; //停止交管线程
                    isConnectServer = false;//服务端连接线程停止       
                    this.listTraffic.Clear();//清空列表
                    CommonMethods.ListPreTraffic.Clear();//清空交管列表
                    CommonMethods.isDisplyTraffic = true;//显示交管信息
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
       private  void triffer()
        {


             
        }
        private void AcceptInfo(int num, AsyncUserToken token)
        {
            try
            {
                if (num == 1)
                {
                    string remoteIP = string.Empty; 
                    if (token.Remote != null)
                    {
                        remoteIP = token.IPAddress.ToString();                      
                        //上线IP列表数据加载
                        this.LoginIPList.Add(remoteIP);
                        if (token.IPAddress != null)
                            LoginListShow(token.IPAddress.ToString(), true); //在线状态刷新
                        
                        //AGV在线状态刷新
                        if (token.IPAddress != null)
                            UpdateAGVStatus(true, token.IPAddress.ToString());
                    }
                    
                }
                else if(num == -1)
                {
                    if (token != null)
                    {                                           
                        ///从列表中移除被中断的连接 ip:Port 
                        if(token.Remote !=null)
                        this.LoginIPList.Remove(token.Remote.ToString());
                        if (token.IPAddress != null)
                            LoginListShow(token.IPAddress.ToString(),false); //在线状态刷新
                        if (token.IPAddress != null)
                        {
                            //AGV在线状态刷新
                            UpdateAGVStatus(false, token.IPAddress.ToString());
                            
                        }
                        
                    }
                }
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message,"错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
            }
            
        }
        private void ReMsg(AsyncUserToken token, byte[] buffer)
        {
            try
            {
                lock (obj)
                {
                    if (token.IPAddress != null)
                    {
                        string ip = token.IPAddress.ToString();//获取IP地址           
                        AGVInfo objPreAGVInfo = listLastAGVInfo.Find(s => s.IP == ip.ToString()); //根据IP寻找到当前AGV其他信息

                       // AGVInfo objAgvData = objAGVCommunicationManager.ResolutionProtocol2(token, buffer); //AGV协议信息的解析
                       // if (objAgvData != null) UpdateAGVStatus(objAgvData);
                        // this.toolStripStatusLabel6.Text = token.BufferCount.ToString();     //显示接收字节数        
                    }
                }

            }
            catch (Exception ex)
            {
                //throw new Exception(ex.Message);
                MessageBox.Show("AGV信息接收异常或状态数据更新异常！异常详细信息：" + ex.Message);
            }


        }
        private void ReceiveMsg(AsyncUserToken token, byte[] buffer)
        {
            try
            {
                lock (obj)
                {
                    if (token.IPAddress != null)
                    {
                        string ip = token.IPAddress.ToString();//获取IP地址           
                        AGVInfo objPreAGVInfo = listLastAGVInfo.Find(s => s.IP == ip.ToString()); //根据IP寻找到当前AGV其他信息

                        AGVInfo objAgvData = objAGVCommunicationManager.ResolutionProtocol2(token, buffer); //AGV协议信息的解析
                        if (objAgvData != null) UpdateAGVStatus(objAgvData);
                       // this.toolStripStatusLabel6.Text = token.BufferCount.ToString();     //显示接收字节数        
                    }
                }
                                                            
            }
            catch (Exception ex)
            {
                //throw new Exception(ex.Message);
                MessageBox.Show("AGV信息接收异常或状态数据更新异常！异常详细信息：" + ex.Message);
            }
            
        }
        #region 远程IO的服务端委托实体函数
        private void RemoteAcceptInfo(int num, AsyncUserToken token)
        {
            try
            {
                if (num == 1)
                {
                    string remoteIP = string.Empty;
                    if (token.Remote != null)
                    {
                        remoteIP = token.Remote.ToString();
                        //上线IP列表数据加载
                        this.LoginIPList.Add(remoteIP);
                        if (token.IPAddress != null)
                            LoginListShow(token.IPAddress.ToString(), true); //在线状态刷新

                    }

                }
                else if (num == -1)
                {
                    if (token != null)
                    {
                        ///从列表中移除被中断的连接 ip:Port 
                        if (token.Remote != null)
                            this.LoginIPList.Remove(token.Remote.ToString());
                        if (token.IPAddress != null)
                        LoginListShow(token.IPAddress.ToString(), false); //在线状态刷新
                        if (token.IPAddress != null) //出现异常
                        {

                            //防止远程IO端开再一次上电无效
                            if (token.IPAddress.ToString() == alarmIP)
                            {
                                alarmSend = false;
                                alarmClear = false;
                            }
                        }

                    }
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }
        private void RemoteReceiveMsg(AsyncUserToken token, byte[] buffer)
        {
            lock (obj1)
            {
                string ip = token.IPAddress.ToString();//获取IP地址            
                List<ExCall> objExCall = objRemoteIOManager.ResolutionProtocol(buffer, token); //获取远程IO的呼叫信息
                //List<ExCall> objExCall = objRemoteIOManager.ResolutionProtocol2(buffer, token); //获取远程IO的呼叫信息
                if (objExCall != null && objExCall.Count != 0) //呼叫的IO没有存在则不显示，只显示存在的IO
                {

                    CommonMethods.ListPreCall.AddRange(objExCall);
                    while (exCallLock) ;//等待处理完再显示
                    CommonMethods.StatndbyCallDisplayFlag = true;//更新显示
                }
            }
            
        }
        #endregion
        /// <summary>
        /// 服务端关闭
        /// </summary>
        private void ServerClose()
        {
            foreach (AsyncUserToken item in this.m_socket.ClientList)
            {
                UpdateAGVStatus(false, item.IPAddress.ToString()); //掉线显示
            }            
            m_socket.Stop(); //服务端停止工作
            remoteSocket.Stop();//远程IO服务端停止
            this.LoginIPList.Clear(); //清空列表
            //this.lbAGV.Invoke(new Action<List<string>>(s =>
            //{
            //    this.lbAGV.DataSource = null;
            //    this.lbAGV.DataSource = LoginIPList; //显示列表清空 
            //}), this.LoginIPList);                    
        }
        private void LoginListShow(string ip,bool state)
        {
            bool flag = false;
            foreach (TreeNode treeNode in this.tvwOnlineStatus.Nodes)
            {
                foreach (TreeNode objNodes in treeNode.Nodes)
                {
                    if (objNodes.Name == ip)
                    {
                        flag = true;
                        if (state)
                        {
                            this.tvwOnlineStatus.Invoke(new Action<string> (s=>
                            {
                                objNodes.Text = objNodes.Tag + " \r\n" + objNodes.Name + "(" + "在线" + ")";
                                objNodes.ForeColor = Color.Green;
                                int count = treeNode.Nodes.Count; //总数
                                int onlineCount = Convert.ToInt32(treeNode.Tag) + 1;
                                treeNode.Tag = onlineCount;//存储在线总数
                                treeNode.Text = treeNode.Name + "(" + onlineCount + "/" + count + ")";
                            }),""); 
                        }
                        else
                        {
                            this.tvwOnlineStatus.Invoke(new Action<string>(s =>
                            {
                                objNodes.Text = objNodes.Tag + " \r\n" + objNodes.Name + "(" + "离线" + ")";
                                objNodes.ForeColor = Color.Red;
                                int count = treeNode.Nodes.Count; //总数
                                int onlineCount = Convert.ToInt32(treeNode.Tag) - 1;
                                treeNode.Tag = onlineCount;//存储在线总数
                                treeNode.Text = treeNode.Name + "(" + onlineCount + "/" + count + ")";
                            }), ""); 
                        }
                        return;
                     }
                    if (flag) break;
                }              
            }
            this.tvwOnlineStatus.Invoke(new Action<string>(s =>
            {
                string txt = "";
                int onLineCount = 0;
                if (state)
                {
                    txt = "(在线)";
                    onLineCount = Convert.ToInt32(this.tvwOnlineStatus.Nodes[2].Tag) + 1;
                    TreeNode objTreeNodes = new TreeNode()
                    {
                        Name = ip,
                        Text = ip + txt,
                        Tag = "",
                        ForeColor = Color.Green
                    };
                    this.tvwOnlineStatus.Nodes[2].Nodes.Add(objTreeNodes);
                    this.tvwOnlineStatus.Nodes[2].Tag = onLineCount;
                    this.tvwOnlineStatus.Nodes[2].Text = this.tvwOnlineStatus.Nodes[2].Name + "(" + onLineCount + "/" + this.tvwOnlineStatus.Nodes[2].Nodes.Count + ")";
                }
            }), ""); 
        }
       
        #endregion

        #region 交通管制线程
        private void StartTrafficThread(bool cmd)
        {
            //开启线程
            if (cmd)
            {
                if (this.objTrafficThread == null)
                {
                    this.objTrafficThread = new Thread(TrafficThread);//创建一个交管的线程
                    this.objTrafficThread.IsBackground = true;//该线程为后台线程
                    this.objTrafficThread.Start();//开始线程
                }
                isStartTraffic = true; //启动交管线程
            }
            //关闭线程
            else
            {
                if (this.objTrafficThread != null)
                {
                    this.objTrafficThread.Interrupt();
                    this.objTrafficThread.Abort();
                    this.objTrafficThread = null;
                }
            }
        }
        private Thread objTrafficThread = null;
        /// <summary>
        /// 交管线程
        /// </summary>
        /// <param name="o">当前AGV详细信息</param>
        private void TrafficThread( )
        {
            while (true)
            {                
                if (isStartTraffic)
                {
                    try
                    {
                        isFinishTrafficControl = true;
                        //objTrafficManager.TrafficControl(listTraffic, this.dgvAGV, this.objServerHelper.SocketDic, this.listTrafficOrder,this.dgvTrafficView); //执行交管
                        //foreach (DataGridViewRow dgvrow in dgvAGV.Rows)
                        for (int i = 0; i < dgvAGV.Rows.Count;i++ )
                        {
                            //封装AGV当前信息
                            AGVInfo objAGV = new AGVInfo()
                            {
                                AGVName = this.dgvAGV.Rows[i].Cells["AGVName"].Value != null ? this.dgvAGV.Rows[i].Cells["AGVName"].Value.ToString() : "",
                                IP = this.dgvAGV.Rows[i].Cells["IP"].Value != null ? this.dgvAGV.Rows[i].Cells["IP"].Value.ToString() : "",
                                PreLandNum = this.dgvAGV.Rows[i].Cells["PreLandNum"].Value != null ? Convert.ToInt32(this.dgvAGV.Rows[i].Cells["PreLandNum"].Value) : 0,
                                PreAGVStatus = this.dgvAGV.Rows[i].Cells["PreAGVStatus"].Value != null ? this.dgvAGV.Rows[i].Cells["PreAGVStatus"].Value.ToString() : "",
                                OnLineStatus = this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value != null ? this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value.ToString() : "",
                            };

                            //【1】先判断状态是否合适
                            if (objAGV.PreAGVStatus != "失联" && objAGV.OnLineStatus != "离线")
                            {
                                //【2】地标判断，不能为0
                                if (objAGV.PreLandNum != 0)
                                {
                                    //【3】查询地标是否存在交管功能
                                    List<TrafficInfo> listTrafficCmd = this.listTrafficOrder.FindAll(s => s.LandNum == objAGV.PreLandNum);
                                    //List<TrafficInfo> listTrafficCmd =objTrafficManager.GettrafficInfoByLandNum(objAGV.PreLandNum.ToString());
                                    //【4】如果存在交管功能则进入
                                    if (listTrafficCmd.Count != 0)
                                    {
                                        //【5】进入交管管理算法
                                        foreach (TrafficInfo item in listTrafficCmd)
                                        {
                                            /*-----------------------------------------------------------管制指令执行-----------------------------------------------------------*/
                                            if (item.CMD == 0)
                                            {
                                                int landNum = this.dgvAGV.Rows[i].Cells["PreLandNum"].Value != null ? Convert.ToInt32(this.dgvAGV.Rows[i].Cells["PreLandNum"].Value) : 0;
                                                if (landNum == objAGV.PreLandNum && item.LandNum == landNum)
                                                {
                                                    //寻找该区域的交管是否已经存在，存在则管制该AGV(需要增加一个状态：是否已被管制主，如果都被管制主，则一直通过交管区域。有没有没管制主，则被管制)
                                                    List<TrafficInfo> listInTraffic = listTraffic.FindAll(s => s.Area == item.Area && s.IP != objAGV.IP);
                                                    //判断在该区域是否已经存在该IP的AGV
                                                    TrafficInfo listIsExistsTraffic = listTraffic.Find(s => s.Area == item.Area && s.IP == objAGV.IP);
                                                    //存在交管AGV && 并不是本AGV
                                                    if (listInTraffic.Count != 0 && listIsExistsTraffic == null)
                                                    {
                                                        //发送停止信号
                                                        OrderList objOrderList = new OrderList() { CMD = 0x14 };
                                                        AsyncUserToken objAsyncUserToken = m_socket.ClientList.Find(s => s.Remote.ToString().Contains(objAGV.IP)); //根据IP地址查询Socket变量
                                                        if (objAsyncUserToken != null) m_socket.SendMessage(objAsyncUserToken, objAGVCommunicationManager.GetSendData(objOrderList)); //发送数据
                                                        //objAGVCommunicationManager.SendDataByIP(objAGV.IP, this.objServerHelper.SocketDic, objOrderList);//发送数据
                                                        listTraffic.Add(new TrafficInfo() { AGVName = objAGV.AGVName, IP = objAGV.IP, Area = item.Area, InTraffic = DateTime.Now, TrafficStatus = "管制中", LandNum = objAGV.PreLandNum });
                                                        //CommonMethods.ListPreTraffic = listTraffic; //交管赋值
                                                    }
                                                    else if (listInTraffic.Count == 0 && listIsExistsTraffic == null)
                                                    {
                                                        listTraffic.Add(new TrafficInfo() { AGVName = objAGV.AGVName, IP = objAGV.IP, Area = item.Area, LandNum = objAGV.PreLandNum, InTraffic = DateTime.Now, TrafficStatus = "通行中" });
                                                        //CommonMethods.ListPreTraffic = listTraffic; //交管赋值
                                                    }
                                                }

                                            }
                                            /*-----------------------------------------------------------释放指令执行-----------------------------------------------------------*/
                                            else if (item.CMD == 1)
                                            {
                                                //查找对应区域和交管AGV，并清除该AGV在交管区域的信息（释放交管）
                                                int index = listTraffic.FindIndex(s => s.Area == item.Area && s.IP == objAGV.IP);
                                                if (index != -1)
                                                {
                                                    //释放被管制的AGV,不能寻找自己
                                                    List<TrafficInfo> listOutTraffic = listTraffic.FindAll(s => s.Area == item.Area && s.IP != objAGV.IP);
                                                    if (listOutTraffic.Count != 0)
                                                    {
                                                        //发送释放信号
                                                        Thread.Sleep(200); //延时200ms再发释放，以防AGV不释放
                                                        OrderList objOrderList = new OrderList() { CMD = 0x15 };
                                                        //objAGVCommunicationManager.SendDataByIP(listOutTraffic[0].IP, this.objServerHelper.SocketDic, objOrderList);//发送数据 释放最前面一台
                                                        AsyncUserToken objAsyncUserToken = m_socket.ClientList.Find(s => s.IPAddress.ToString() == listOutTraffic[0].IP); //根据IP地址查询Socket变量
                                                        if (objAsyncUserToken != null) m_socket.SendMessage(objAsyncUserToken, objAGVCommunicationManager.GetSendData(objOrderList)); //发送数据
                                                        int outIndex = listTraffic.FindIndex(s => s.Area == item.Area && s.IP == listOutTraffic[0].IP);
                                                        lock (listTraffic)
                                                        {
                                                            if (outIndex != -1) listTraffic[outIndex].TrafficStatus = "通行中";
                                                        }
                                                    }
                                                    listTraffic.RemoveAt(index); //删除当前运行出交管区域的AGV信息   
                                                    //CommonMethods.ListPreTraffic = listTraffic; //交管赋值
                                                }
                                            }
                                        }//交管管理算法
                                    }//end 是否存在交管指令
                                } //end 地标判断
                            }//end 状态分析
                        }
                        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        isFinishTrafficControl = false; //解锁可以处理其他信息
                        if (this.listTraffic.Count != 0)
                        {
                            this.listTraffic.Sort(new AreaASC());
                            
                        }
                        CommonMethods.ListPreTraffic = listTraffic; //交管赋值
                        CommonMethods.isDisplyTraffic = true;
                        Thread.Sleep(200);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "交管提示");                       
                    }                   
                }                
            }
        }
       
        #endregion

        #region 客户端连接线程
        /// <summary>
        /// 创建一个线程
        /// </summary>
        /// <param name="isStart"></param>
        private void StartClientConnectThread(bool isStart)
        {
            //创建一个交管的现场
            //ParameterizedThreadStart pts = new ParameterizedThreadStart(TrafficThread);
            Thread th = new Thread(ClientConnectThread);
            th.IsBackground = true; //该线程为后台线程
            if (isStart) th.Start(); //开始线程
            else th.Abort();
            this.isConnectServer = true; //运行连接服务端线程开关打开
        }
        /// <summary>
        /// 客户端实时接收服务端数据线程的执行
        /// </summary>
        private void ClientConnectThread()
        {
            while (true)
            {
                if (this.isConnectServer)
                {
                    try
                    {
                        for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
                        {
                            string ip = this.dgvAGV.Rows[i].Cells["IP"].Value.ToString(); //获取IP
                            AGVInfo objAGVInfo = listLastAGVInfo.Find(s => s.IP == ip);//寻找对应IP地址信息
                            SocketClientManager objSocketClientManager = new SocketClientManager();

                            if (!dicSocketClient.ContainsKey(ip))
                            {
                                SocketError socketError = objSocketClientManager.Connect(objAGVInfo.IP, objAGVInfo.Port);
                                
                                if (socketError == SocketError.Success)
                                {
                                    if (objSocketClientManager.Connected)
                                    {
                                        objSocketClientManager.OnReceiveData += RecMsg;  //关联客户端接收事件
                                        objSocketClientManager.OnServerClosed += ClientClose; //关联服务端断开事件
                                        this.dicSocketClient.Add(ip, objSocketClientManager);  //增加一个服务端连接的集合
                                        //上线列表显示
                                        this.LoginIPList.Add(objAGVInfo.IP);
                                        //this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);
                                        //AGV在线状态刷新
                                        UpdateAGVStatus(true, ip.ToString());
                                    }
                                }
                            }
                            else if (dicSocketClient.ContainsKey(ip)) //如果改IP已经存在列表，如果断开连接则立马清除连接列表中信息
                            {
                                if (!dicSocketClient[ip].Connected)
                                {
                                    this.dicSocketClient.Remove(ip);
                                    //上线列表显示
                                    this.LoginIPList.Remove(ip);
                                    //this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);
                                    //AGV在线状态刷新
                                    UpdateAGVStatus(false, ip.ToString());
                                }
                            }
                        }
                    }
                    catch (SocketException ex)
                    {
                        MessageBox.Show("服务端连接异常，异常信息："+ex.Message,"连接");
                    }
                    catch (Exception ex)
                    {

                        MessageBox.Show(ex.Message,"连接");
                    }
                                       
                }
                Thread.Sleep(5000);
            }
        }
     
        /// <summary>
        /// 服务端数据接收事件
        /// </summary>
        /// <param name="rec">接收数组</param>
        /// <param name="ip">服务端的IP</param>
        private void RecMsg(object rec,string ip)
        {
            try
            {
                byte[] buffer = (byte[])rec;
                AGVInfo objPreAGVInfo = listLastAGVInfo.Find(s => s.IP == ip); //根据IP寻找到当前AGV其他信息
                if (objPreAGVInfo != null)
                {
                    AGVInfo objAgvData = objAGVCommunicationManager.ResolutionProtocol(buffer, objPreAGVInfo); //AGV协议信息的解析
                    UpdateAGVStatus(objAgvData);
                }
            }
            catch (SocketException ex)
            {
                MessageBox.Show(ip + "数据接收异常!异常信息" + ex.Message, "接收");
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message,"服务器异常");
            }
                       
            //string str = new SerialPortHelper.AlgorithmHelper().BytesTo16(data, SerialPortHelper.Enum16Hex.Blank);
            //MessageBox.Show(str + ip);
        }
        /// <summary>
        /// 服务端断开事件
        /// </summary>
        /// <param name="ip"></param>
        private void ClientClose(string ip)
        {
            try
            {
                // MessageBox.Show(ip);
                UpdateAGVStatus(false, ip); //掉线显示
                this.LoginIPList.Remove(ip);
               // this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);               
                dicSocketClient.Remove(ip); //从集合中删除已掉线的AGV
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 服务的断开
        /// </summary>
        private void ServerDisconnect()
        {
            if (this.dicSocketClient.Count != 0)
            {
                //逐一断开服务器的连接
                foreach (SocketClientManager item in this.dicSocketClient.Values)
                {
                    item.Disconnect();                  
                }
                foreach (string  item in this.dicSocketClient.Keys)
                {
                    UpdateAGVStatus(false, item); //掉线显示
                }
            }
            this.dicSocketClient.Clear();//清空服务器连接集合
        }
        #endregion

        #region 调度系统调度线程
        private void TaskScheduling()
        {
            try
            {
                while (true)
                {
                    if (isRun)
                    {
                        exCallLock = true;//显示上锁
                        //执行调度任务并返回完成的数据列表
                        List<ExCall> objListExCall = objAGVCommunicationManager.TaskScheduling(this.dgvAGV,m_socket, CommonMethods.ListPreCall); //更换发送方式
                       // List<ExCall> objListExCall = objAGVCommunicationManager.TaskScheduling(this.dgvAGV, this.dgvStandbyCall, this.objServerHelper.SocketDic, listExCall);
                        //更新已完成派车的列表
                        if (objListExCall.Count != 0)
                        {                            
                            //保存呼叫完成的信息到数据库
                            objRemoteIOManager.AddFinishCallByTran(objListExCall);
                            CommonMethods.StatndbyCallDisplayFlag = true; //更新未完成呼叫列表
                        }
                        exCallLock = false;//解锁                                
                    }
                    Thread.Sleep(5000);
                }
            }
            catch (Exception ex)
            {
                
                MessageBox.Show(ex.Message);
            }
            
        }
        #endregion

        #region 电子地图显示线程
        private void MapDispalyThread()
        {
            bool switchFlag = false;
            while(true)
            {
                foreach (DataGridViewRow row in this.dgvAGV.Rows)
                {                 
                    string agvName = row.Cells["AGVName"].Value.ToString(); //AGV名称
                    int preLandNum =Convert.ToInt32( row.Cells["PreLandNum"].Value);//地标号
                    string agvStatus = row.Cells["PreAGVStatus"].Value.ToString();//当前状态
                    LandNode objLandNode = this.currentListNodes.Find(s=>s.LandNum == preLandNum); //获取当前的地标号的信息
                    Label preLabel = this.listAGVLabel.Find(s => s.Name == agvName);
                    if (preLabel != null && objLandNode != null)
                    {
                        preLabel.Invoke(new Action<LandNode>((s) =>
                        {
                            Point objPoint = new Point(s.X,s.Y);
                            preLabel.Location = objPoint;
                            //根据状态来改变显示的颜色
                            switch (agvStatus)
                            { 
                                case "失联":
                                    preLabel.BackColor = Color.Silver;
                                    preLabel.ForeColor = Color.White;
                                    break;
                                case "待命中":
                                    preLabel.BackColor = Color.Brown;
                                    preLabel.ForeColor = Color.White;
                                    break;
                                case "交管状态":
                                    preLabel.BackColor = Color.Yellow;
                                    preLabel.ForeColor = Color.Black;
                                    break;
                                case "红外防撞":
                                    if (switchFlag) 
                                    {
                                        preLabel.BackColor = Color.Yellow;
                                        preLabel.ForeColor = Color.Black;
                                        switchFlag = false;
                                    }
                                    else 
                                    {
                                        preLabel.BackColor = Color.Blue;
                                        preLabel.ForeColor = Color.White;
                                        switchFlag = true;
                                    }
                                    break;
                                default:
                                    preLabel.BackColor = Color.Green;
                                    preLabel.ForeColor = Color.White;
                                    break;
                            }
                        }), objLandNode);  
                       
                    }
                }
                Thread.Sleep(500);
            }
        }
        int originalWidth = 0; //1260
        int originalHeight = 0;//309
        private void GetImageSize()
        {
            PropertyInfo rectangleProperty = this.pictureBoxMap.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
            Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(this.pictureBoxMap, null);
            originalWidth = rectangle.Width; //1294
            originalHeight = rectangle.Height; //385
        }
        private Point LabelPoint(int x, int y)
        {
           // int originalWidth = this.pictureBoxMap.Image.Width; //1260
           // int originalHeight = this.pictureBoxMap.Image.Height;//309
           // //int originalWidth = 1288; //1260
           //// int originalHeight = 379;//309
            int width = 0, height = 0;//定义长宽变量
            width = this.pictureBoxMap.Size.Width; //获取图片高度
            height = this.pictureBoxMap.Size.Height;

            width = (width - 1288) / 4;
            height = (height - 379) / 2;
            PropertyInfo rectangleProperty = this.pictureBoxMap.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
            Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(this.pictureBoxMap, null);

            int currentWidth = rectangle.Width; //1294
            int currentHeight = rectangle.Height; //385
            double rate = (double)currentHeight / (double)originalHeight;

            int black_left_width = (currentWidth == this.pictureBoxMap.Width) ? 0 : (currentWidth - originalWidth) / 4;
            int black_top_height = (currentHeight == this.pictureBoxMap.Height) ? 0 : (currentHeight - originalHeight) / 2;

            int zoom_x = x + black_left_width + width;
            int zoom_y = y + black_top_height + height;

            double original_x = (double)zoom_x / rate;
            double original_y = (double)zoom_y / rate;
            
            return new Point(zoom_x, zoom_y);
           
        }

        #endregion

        #region AGV状态刷新
        /// <summary>
        /// 刷新AGV在线状态
        /// </summary>
        /// <param name="status">true:上线 false:掉线</param>
        /// <param name="ip">IP地址</param>
        private void UpdateAGVStatus(bool status,string ip)
        {
            try
            {
                //this.dgvAGV.Invoke(new Action<string, bool>((s, a) =>
                //{
                    //查找登录的客户端IP地址，并显示当前在线状态
                    for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
                    {
                        if (this.dgvAGV.Rows[i].Cells["IP"].Value.ToString() == ip)
                        {
                            if (status == true)
                            {
                                if (CommonMethods.LanguageId == 3) this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = "オンライン";
                                else this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = "在线";
                                this.dgvAGV.Rows[i].Cells["UpdateTime"].Value = DateTime.Now;
                            }
                            else
                            {
                                //this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = "离线";
                                if (CommonMethods.LanguageId == 3) this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = "線を離す";
                                else this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = "离线";
                            }
                            break;
                        }
                    }
                //}), ip, status);
            }
            catch (Exception ex)
            {
                
                MessageBox.Show("状态更新异常！异常信息："+ex.Message);
            }
            
        }
        /// <summary>
        /// 更新AGV状态
        /// </summary>
        /// <param name="objAGV"></param>
        private void UpdateAGVStatus(AGVInfo objAGV)
        {
            //this.dgvAGV.BeginInvoke(new Action<AGVInfo>(s =>
            //{
                for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
                {
                    if (this.dgvAGV.Rows[i].Cells["IP"].Value.ToString() == objAGV.IP)
                    {
                        //this.dgvAGV.Rows[i].Cells["IP"].Value = s.IP;
                        //this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = s.OnLineStatus;
                        this.dgvAGV.Rows[i].Cells["PreAGVStatus"].Value = objAGV.PreAGVStatus;
                        this.dgvAGV.Rows[i].Cells["AimStation"].Value = objAGV.AimStation;
                        this.dgvAGV.Rows[i].Cells["PreLandNum"].Value = objAGV.PreLandNum;
                        this.dgvAGV.Rows[i].Cells["LiftStatus"].Value = objAGV.LiftStatus;
                        this.dgvAGV.Rows[i].Cells["Speed"].Value = objAGV.Speed;
                        this.dgvAGV.Rows[i].Cells["Electricity"].Value = objAGV.Electricity;
                        this.dgvAGV.Rows[i].Cells["UpdateTime"].Value = objAGV.UpdateTime;
                        //this.dgvAGV.Rows[i].Cells["AGVName"].Value = s.AGVName;
                       // this.dgvAGV.Rows[i].Cells["TrackName"].Value = s.TrackName;
                        break;
                    }
                }
            //}), objAGV);
        }
        #endregion

        #region 系统退出
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result ;
            if (CommonMethods.LanguageId == 3) result = MessageBox.Show("脱退システムを確認しますか？", "ヒントを退く", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            else result = MessageBox.Show("确认退出系统？", "退出提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
            else
            {
                new BLL.SysAdminManager().WriteLogOutInfo(Program.currentAdmins.LoginId.ToString()); //退出记录编写
            }
        }

        private void 退出系统QToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion

        #region 定时器工作
        private void timAGVStaus_Tick(object sender, EventArgs e)
        {
            this.lblSysTime.Text = sysRunTime.Elapsed.Days + "天" + sysRunTime.Elapsed.Hours + "小时" + sysRunTime.Elapsed.Minutes + "分" + sysRunTime.Elapsed.Seconds + "秒"; //运行时间显示
            this.lblThreadCount.Text ="线程数量："+ Process.GetCurrentProcess().Threads.Count.ToString();  //线程数统计
            //ShowTrafficView();//交管显示
            for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
            {
                DateTime dt = Convert.ToDateTime(this.dgvAGV.Rows[i].Cells["UpdateTime"].Value); //获取上次更新时间
                DateTime dtNow = DateTime.Now;
                int second = (dtNow - dt).Seconds;
                if ( second> 5)
                {
                    //this.dgvAGV.Invoke(new Action<int>((s) => { this.dgvAGV.Rows[s].Cells["PreAGVStatus"].Value = "失联"; }), i);
                    if (CommonMethods.LanguageId == 3) this.dgvAGV.Rows[i].Cells["PreAGVStatus"].Value = "連係を失う";
                    else this.dgvAGV.Rows[i].Cells["PreAGVStatus"].Value = "失联";
                    string ip = this.dgvAGV.Rows[i].Cells["IP"].Value.ToString(); //获取IP                 
                    //当AGV超时没有上传状态时则重新发送上传状态
                   // foreach (AsyncUserToken item in this.m_socket.ClientList)
                    for (int j = 0; j < this.m_socket.ClientList.Count;j++ )
                    {
                        if (this.m_socket.ClientList[j].Socket.Connected && this.m_socket.ClientList[j].IPAddress.ToString() == ip)
                        {
                            try
                            {
                                OrderList objOrderList = new OrderList() { CMD = 22, Data = 1 };
                                //bool sendStatus = objAGVCommunicationManager.SendDataByIP(item.IPAddress.ToString(), this.objServerHelper.SocketDic, objOrderList);//发送数据 启动自动上报信息
                                m_socket.SendMessage(this.m_socket.ClientList[j], objAGVCommunicationManager.GetSendData(objOrderList)); //发送数据
                                if ((dtNow - dt).Seconds > 15)
                                {
                                    m_socket.CloseClient(this.m_socket.ClientList[j]);
                                    this.LoginIPList.Remove(this.m_socket.ClientList[j].IPAddress.ToString()); //清除显示
                                   // LoginListShow(this.m_socket.ClientList[j].IPAddress.ToString(), false); //在线状态刷新
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                m_socket.CloseClient(this.m_socket.ClientList[j]);
                                this.LoginIPList.Remove(this.m_socket.ClientList[j].IPAddress.ToString()); //清除显示
                                //LoginListShow(this.m_socket.ClientList[j].IPAddress.ToString(), false); //在线状态刷新
                                //LoginListShow();
                                break;
                                //MessageBox.Show("定时器刷新失败！异常信息：" + ex.Message);
                            }
                        }
                    }                            
                }
            }                           
          }
         #endregion

        #region 窗体打开
        public static FrmAGVEdit objFrmAGVEdit = null;
        private void 添加AGVToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmAGVEdit == null)
            {
                objFrmAGVEdit = new FrmAGVEdit();
                //委托办法关联
                objFrmAGVEdit.showAGVInfo += ShowAGVInfo;//委托办法的关联
                objFrmAGVEdit.Show();
            }
            else
            {
                objFrmAGVEdit.Activate();//激活只能在最小化的时候起作用
                objFrmAGVEdit.WindowState = FormWindowState.Normal; 
            }
        }
        public static FrmManualControl objFrmManualControl = null;
        private void 手动控制CToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmManualControl == null)
            {
                objFrmManualControl = new FrmManualControl();
                objFrmManualControl.objServerSend += SendData;//委托办法的关联
                objFrmManualControl.Show();
            }
            else
            {
                objFrmManualControl.Activate();//激活只能在最小化的时候起作用
                objFrmManualControl.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmManualCall objFrmManualCall = null;
        private void 手动添加任务ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmManualCall == null)
            {
                objFrmManualCall = new FrmManualCall();
                objFrmManualCall.ImportCallInfo += LoadCallInfo;//委托办法的关联
                objFrmManualCall.Show();
            }
            else
            {
                objFrmManualCall.Activate();//激活只能在最小化的时候起作用
                objFrmManualCall.WindowState = FormWindowState.Normal;
            }
        }

        public static FrmEditRemoteIO objFrmEditRemoteIO = null;
        private void 呼叫编辑CToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmEditRemoteIO == null)
            {
                objFrmEditRemoteIO = new FrmEditRemoteIO();
                objFrmEditRemoteIO.ipTypeOutput += ShowTypeIP;//委托办法的关联
                objFrmEditRemoteIO.Show();
            }
            else
            {
                objFrmEditRemoteIO.Activate();//激活只能在最小化的时候起作用
                objFrmEditRemoteIO.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmTrafficEdit objFrmTrafficEdit = null;
        private void 交通管制编辑TToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmTrafficEdit == null)
            {
                objFrmTrafficEdit = new FrmTrafficEdit();
                //objFrmEditRemoteIO.ipTypeOutput += ShowTypeIP;//委托办法的关联
                objFrmTrafficEdit.Show();
            }
            else
            {
                objFrmTrafficEdit.Activate();//激活只能在最小化的时候起作用
                objFrmTrafficEdit.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmTrafficView objFrmTrafficView = null;
        private void 交管显示VToolStripMenuItem_Click(object sender, EventArgs e)
        {
            btnDebug_Click(null,null);
        }
        public static FrmWatchBoard objFrmWatchBoard = null;
        private void 看板系统显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmWatchBoard == null)
            {
                objFrmWatchBoard = new FrmWatchBoard();
                this.WatchBoarShow += objFrmWatchBoard.Receiver; ;//委托办法的关联
                objFrmWatchBoard.Show();
                this.timWatchBoard.Start(); //开启时钟
            }
            else
            {
                objFrmWatchBoard.Activate();//激活只能在最小化的时候起作用
                objFrmWatchBoard.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmQuery objFrmQuery = null;
        private void 完成数据查询FToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmQuery == null)
            {
                objFrmQuery = new FrmQuery();
                objFrmQuery.Show();

            }
            else
            {
                objFrmQuery.Activate();//激活只能在最小化的时候起作用
                objFrmQuery.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmLogQuery objFrmLogQuery = null;
        private void 登录日志LToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmLogQuery == null)
            {
                objFrmLogQuery = new FrmLogQuery();
                objFrmLogQuery.Show();

            }
            else
            {
                objFrmLogQuery.Activate();//激活只能在最小化的时候起作用
                objFrmLogQuery.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmMapEdit objFrmMapEdit = null;//设窗体为静态成员，赋值null
        private void 新增地图AToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmMapEdit == null)
            {
                objFrmMapEdit = new FrmMapEdit();
                objFrmMapEdit.Show();

            }
            else
            {
                objFrmMapEdit.Activate();//激活只能在最小化的时候起作用
                objFrmMapEdit.WindowState = FormWindowState.Normal;
            }
        }
        private void 导入地图IToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmMapOperation objFrmMapOperation = new FrmMapOperation("1");
            //将从窗体的委托变量和主窗体的对应方法关联
            objFrmMapOperation.openProjectSender = this.OpenProjectReceiver;
            objFrmMapOperation.ShowDialog();
        }
        private void OpenProjectReceiver(FileNameAddress objFileNameAddress)
        {
            this.Text = "【AGV调度系统】-- 项目工程："+objFileNameAddress.FileName;
            //【1】加载图片
           // LoadPicture(objFileNameAddress.ID.ToString());
            //【2】保存当前的工程ID到ProjectConfig.ini
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "项目编号", objFileNameAddress.ID.ToString());
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "工程名称", objFileNameAddress.FileName);
            //【3】加载数据
            MapPictureInit();
        }
        private void LoadPicture(string id)
        {
            try
            {
                PictureFile currentPictureFile =new  PictureFileManager().GetPictureById(id);
                //如果没有找到，既没有图片则显示默认图片
                if (currentPictureFile == null)
                {
                    this.pictureBoxMap.Image = Image.FromFile("default.png");
                    currentPictureFile = new PictureFile();//重新实例化，避免下面使用出现异常
                }
                else
                {
                    this.pictureBoxMap.Image = currentPictureFile.StuImage.Length != 0 ?
                        (Image)new Common.SerializeObjectToString().DeserializeObject(currentPictureFile.StuImage) : Image.FromFile("default.png");
                    GetImageSize();//获取图片尺寸
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("图片加载异常，异常详细信息：" + ex.Message);
            }
        }
        #endregion

        #region 看板系统
        private void timWatchBoard_Tick(object sender, EventArgs e)
        {
            if (objFrmWatchBoard != null)
            {
                int AGVCount = this.dgvAGV.Rows.Count;//AGV数量
                int onLineCount = 0; //上线AGV数量
                int outLintCount = 0;//下线AGV数量
                int remoteIOCount = 0;//IO上线数量
                foreach (DataGridViewRow item in dgvAGV.Rows)
                {
                    if(item.Cells["OnLineStatus"].Value!=null)
                    if (item.Cells["OnLineStatus"].Value.ToString() == "在线")
                    {
                        onLineCount++;
                    }
                }
                if (AGVCount != 0)
                    outLintCount = AGVCount - onLineCount;
                //if(this.lbAGV.Items.Count !=0)
                //{
                //    remoteIOCount = this.lbAGV.Items.Count - onLineCount;
                //}
                
                WatchBoards objWatchBoards = new WatchBoards()
                {
                    AGVOnlineCount = onLineCount,
                    AGVOutCount = outLintCount,
                    RemoteIOCount = remoteIOCount
                };
                WatchBoarShow.Invoke(objWatchBoards);
            }
            else
            {
                this.timWatchBoard.Stop();
            }
        }
        #endregion

        #region 报警显示
        private void timAlarm_Tick(object sender, EventArgs e)
        {
            bool isExistsAlarm = false; //是否存在异常
            //获取报警状态
            foreach (DataGridViewRow item in this.dgvAGV.Rows)
            {
                if (objAGVCommunicationManager.GetAlarmFlag(item.Cells["PreAGVStatus"].Value.ToString(), item.Cells["OnLineStatus"].Value.ToString()))
                {
                    isExistsAlarm = true;
                    break;
                }
            }
            //根据AGV当前状态改变显示颜色
            foreach (DataGridViewRow row in this.dgvAGV.Rows)
            {
                if (row.Cells["PreAGVStatus"].Value.ToString() == "失联" || row.Cells["OnLineStatus"].Value.ToString() == "离线"
                    || row.Cells["PreAGVStatus"].Value.ToString() == "連係を失う" || row.Cells["OnLineStatus"].Value.ToString() == "線を離す")
                {
                    row.Cells["PreAGVStatus"].Style.BackColor = Color.Red;
                    row.Cells["OnLineStatus"].Style.BackColor = Color.Red;
                    row.Cells["PreAGVStatus"].Style.ForeColor = Color.White; //字体白色
                    row.Cells["OnLineStatus"].Style.ForeColor = Color.White; //字体白色
                }
                else if (objAGVCommunicationManager.GetAlarmFlag(row.Cells["PreAGVStatus"].Value.ToString(), row.Cells["OnLineStatus"].Value.ToString()))
                {
                    row.Cells["PreAGVStatus"].Style.BackColor = Color.Red;
                    row.Cells["PreAGVStatus"].Style.ForeColor = Color.White; //字体白色
                }
                else if (row.Cells["PreAGVStatus"].Value.ToString() == "交管状态" || row.Cells["PreAGVStatus"].Value.ToString() == "红外防撞"
                          || row.Cells["PreAGVStatus"].Value.ToString() == "パイプの状態" || row.Cells["PreAGVStatus"].Value.ToString() == "赤外線対策")
                {
                    row.Cells["PreAGVStatus"].Style.BackColor = Color.Yellow;
                    row.Cells["PreAGVStatus"].Style.ForeColor = Color.Black; //字体白色
                }
                else
                {
                    row.Cells["PreAGVStatus"].Style.BackColor = Color.Green;
                    row.Cells["OnLineStatus"].Style.BackColor = Color.Green;
                    row.Cells["PreAGVStatus"].Style.ForeColor = Color.White; //字体白色
                    row.Cells["OnLineStatus"].Style.ForeColor = Color.White; //字体白色
                }
            }
            try
            {
                if (isExistsAlarm && alarmSend == false)
                {                    
                    if (objAGVCommunicationManager.SendRemoteIOByIP(remoteSocket, alarmIP, true))
                    {
                        alarmSend = true;
                        alarmClear = false;
                    }
                }
                else if (isExistsAlarm == false && alarmClear == false)
                {              
                    if (objAGVCommunicationManager.SendRemoteIOByIP(remoteSocket, alarmIP, false)) 
                    {
                        alarmSend = false;
                        alarmClear = true;
                    }
                }
            }
            catch (Exception ex) 
            {

                MessageBox.Show("报警信息发送失败！异常详细信息："+ex.Message);
            }

        }
        #endregion

        #region 窗体打开2
        private void pictureBoxMap_MouseMove(object sender, MouseEventArgs e)
        {
            this.lblLocation.Text = "X:"+e.X.ToString() + "  Y:"+ e.Y.ToString();
        }
        /// <summary>
        /// 关闭窗体通用方法
        /// </summary>
        /// <param name="FrmName"></param>
        /// <returns></returns>
        private bool CloseWindow(string FrmName)
        {
            bool res = false;
            foreach (Control ct in this.splitContainer2.Panel1.Controls)//遍历splitContainer2控件
            {
                if (ct is Form)//有窗体控件的
                {
                    Form Frm = (Form)ct;//强制转换成窗体
                    if (Frm.Name == FrmName)//获取强制转换的窗体名称
                    {
                        res = true;//如果对的上就输出 true
                        break;
                    }
                    else
                    {
                        CommonMethods.isDisplyTraffic = false;//交管显示线程关闭
                        Frm.Close();
                    }
                }
            }
            return res;
        }

        /// <summary>
        /// 打开窗体通用方法
        /// </summary>
        /// <param name="Frm"></param>
        private void OpenWindow(Form Frm)
        {
            Frm.TopLevel = false;//将子窗体设置成非顶级控件      
            Frm.FormBorderStyle = FormBorderStyle.None;//去掉子窗体的边框
            Frm.Dock = DockStyle.Fill;//随着容器大小自动调整窗体大小
            Frm.Parent = this.splitContainer2.Panel1;//指定子窗体显示的容器 
            Frm.BringToFront();//置于顶层 
            Frm.Show();
        }
        private void CloseAllWindows()
        {
            foreach (Control ct in this.splitContainer2.Panel1.Controls)
            {
                if (ct is Form)
                {
                    CommonMethods.isDisplyTraffic = false;//交管显示线程关闭
                    Form Frm = (Form)ct;                   
                    Frm.Close();  
                  
                }
            }
        }
        private void btnMapView_Click(object sender, EventArgs e)
        {
            CloseAllWindows();
            this.btnMapView.BackColor = Color.SkyBlue;
            this.btnCallView.BackColor = Color.White;
            this.btnDebug.BackColor = Color.White;
        }

        private void btnCallView_Click(object sender, EventArgs e)
        {
            if (CloseWindow("FrmCallView") == false)
            {
                OpenWindow(new FrmCallView());
                this.btnMapView.BackColor = Color.White;
                this.btnCallView.BackColor = Color.SkyBlue;
                this.btnDebug.BackColor = Color.White;
            }
        }

        private void btnDebug_Click(object sender, EventArgs e)
        {
            if (CloseWindow("FrmDebug") == false)
            {
                OpenWindow(new FrmDebug());
                this.btnMapView.BackColor = Color.White;
                this.btnCallView.BackColor = Color.White;
                this.btnDebug.BackColor = Color.SkyBlue;
            }
        }

        private void 隐藏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.splitContainer1 .Panel1Collapsed)
            {
                this.splitContainer1.Panel1Collapsed = false; // 展开
                ToolStripMenuItem P_ts = (ToolStripMenuItem)menuStrip1.Items[1];// 得到文件菜单项
                ToolStripMenuItem P_ts2 = (ToolStripMenuItem)P_ts.DropDownItems[3]; // 得到子菜单项
                P_ts2.Text = "隐藏（&H）";
            }
            else
            {
                this.splitContainer1.Panel1Collapsed = true; // 收缩
                ToolStripMenuItem P_ts = (ToolStripMenuItem)menuStrip1.Items[1];// 得到文件菜单项
                ToolStripMenuItem P_ts2 = (ToolStripMenuItem)P_ts.DropDownItems[3]; // 得到子菜单项
                P_ts2.Text = "展开（&O）";
            }
        }
        #endregion

        #region 语言选择
        private void 中文CToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //【1】保存当前的语言ID到ProjectConfig.ini
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "语言", "zh-CN");
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "语言ID", "1");
           // System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
        }

        private void 英文EToolStripMenuItem_Click(object sender, EventArgs e)
        {
          //【1】保存当前的语言ID到ProjectConfig.ini
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "语言", "en-US");
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "语言ID", "2");
            //System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
        }

        private void 日文JToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //【1】保存当前的语言ID到ProjectConfig.ini
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "语言", "ja-JP");
            new Common.INIFileHelper(filePath).IniWriteValue("工程文件", "语言ID", "3");
           // System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ja-JP");
        }
        #endregion

        private void FrmMain_SizeChanged(object sender, EventArgs e)
        {
            //电子地图居中显示
            this.pictureBoxMap.Top = (this.splitContainer2.Panel1.Height - this.pictureBoxMap.Height) / 2;
            this.pictureBoxMap.Left = (this.splitContainer2.Panel1.Width - this.pictureBoxMap.Width) / 2;
        }

        private void lblLocalIP_Click(object sender, EventArgs e)
        {
            FrmIPEdit objFrmIPEdit = new FrmIPEdit();
            DialogResult result = objFrmIPEdit.ShowDialog();
            if (result == DialogResult.OK)
            {
                this.lblLocalIP.Text = CommonMethods.ServerLocalIP;
            }
        }

        private void 信息FToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
        //定时添加实现
        //private void AddAgv(object sender, System.Timers.ElapsedEventArgs e)
        //{
        //    for (int i = 0; i < m_socket.ClientList.Count; i++)
        //    {


        //        string ip = m_socket.ClientList[i].IPAddress.ToString();//获取IP地址           
        //        AGVInfo objPreAGVInfo = listLastAGVInfo.Find(s => s.IP == ip.ToString()); //根据IP寻找到当前AGV其他信息
        //        if (objPreAGVInfo != null)
        //        {
        //            var data = m_socket.SocketReceiveData(m_socket.ClientList[i].Socket);
        //            AGVInfo objAgvData = objAGVCommunicationManager.ResolutionProtocol2(m_socket.ClientList[i], data);
        //            //  AGVInfo objAgvData = objAGVCommunicationManager.ResolutionProtocol2(m_socket.ClientList[i]); //AGV协议信息的解析
        //            //根据ip获取当前agv编号
        //            var AGvip = infoManager.GetAGVId(ip);
        //            //获取名称
        //            var AGvName = infoManager.GetAGVName(ip);
        //            //添加到数据库
        //            var AGVdata = new AGV()
        //            {
        //                AGVID = AGvip,
        //                Device_ID = AGvName,
        //                Process_Code = "CH-AGV-1",
        //                AGVState = objAgvData.PreAGVStatus,
        //                ElectricQ = objAgvData.Electricity.ToString(),
        //                date_time = DateTime.Now,
        //                CurrentSpeed = objAgvData.Speed.ToString(),
        //                CurrentSite = objAgvData.AimStation.ToString(),
        //                Currentid = objAgvData.PreLandNum.ToString()
        //            };
        //            infoManager.AddAGVMessage(AGVdata);
        //        }
        //    }


        //}
        /// <summary>
        /// 启动后一分钟添加，仅以一次
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //private void oneAddAgv(object sender, System.Timers.ElapsedEventArgs e)
        //{

        //    AddAgv(null, null);
        //    s.Stop();
        //}

        private void FrmMain_Load(object sender, EventArgs e)
        {

        }

       
    }
    //交管区域升序排列
    class AreaASC : IComparer<TrafficInfo>
    {
        public int Compare(TrafficInfo x, TrafficInfo y)
        {
            return x.Area - y.Area;
        }
    }

}
